package com.qdlc.p2p.dal.common;

import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import com.qdlc.p2p.common.core.redis.JedisCache;
import com.qdlc.p2p.common.core.redis.JedisCacheFactory;
import com.qdlc.p2p.dal.dao.LogTemplateDao;
import com.qdlc.p2p.dal.dto.LogTemplate;

/**
 * LogTemplate配置文件工具类
 *
 * @author linya 2016-01-26
 */
@Service
public class LogTemplateHelper implements ApplicationContextAware {

    private static ApplicationContext context;

    private static JedisCache<LogTemplate> cache;

    private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    /**
     * 根据nid获取配置值
     *
     * @param nid
     * @return
     */
    public static String getValue(int type, String nid) {
        LogTemplate template = getFromCacheOrDB(type, nid, true);
        return template == null ? "" : template.getValue();
    }

    public static byte getPaymentType(int type, String nid) {
        LogTemplate template = getFromCacheOrDB(type, nid, true);
        return template == null ? 0 : template.getPaymentsType();
    }

    public static String getLogType(int type, String nid) {
        LogTemplate template = getFromCacheOrDB(type, nid, true);
        return template == null ? "" : template.getLogType();
    }

    public static String getLogTempName(int type, String nid) {
        LogTemplate template = getFromCacheOrDB(type, nid, true);
        return template == null ? "" : template.getName();
    }

    private static String wrapKey(int type, String nid) {
        return type + "_" + nid;
    }

    /**
     * 从缓存或者数据库中获取数据
     * 如果cached=true，先从缓存中查找，如果没有，然后从数据库查找。
     * 如果cached=false，强制从数据库获取，并将获取的数据存放到缓存中去。
     *
     * @param nid
     * @param cached
     * @return
     */
    private static LogTemplate getFromCacheOrDB(int type, String nid, boolean cached) {
        LogTemplate template = null;
        try {
            lock.readLock().lock();
            if (cached) {
                template = cache.get(wrapKey(type, nid));
            }
            if (template == null) {
                LogTemplateDao templateDao = context.getBean(LogTemplateDao.class);
                template = templateDao.findObjByProperty("nid", nid);
                cache.set(nid, template);
            }
        } finally {
            lock.readLock().unlock();
        }
        return template;
    }

    /**
     * 初始化配置信息
     *
     * @param context
     */
    private static void initial(ApplicationContext context) {
        LogTemplateDao templateDao = context.getBean(LogTemplateDao.class);
        List<LogTemplate> list = templateDao.findAll();
        if (list != null) {
            for (LogTemplate template : list) {
                cache.set(wrapKey(template.getType(), template.getNid()), template);
            }
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
        cache = JedisCacheFactory.newInstance(LogTemplate.class);
        initial(applicationContext);
    }

}
